package util;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

public class DBUtil {
	static Properties prop = new Properties();
	static {// 静态块

		try {
			prop.load(DBUtil.class.getClassLoader().getResourceAsStream(
					"jdbc.properties"));
			// Class.forName("com.mysql.jdbc.Driver");
			Class.forName(prop.getProperty("driver"));
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();

		}
	}

	// 判断一个字符串是不是为空，包括null和""
	public static boolean isBlank(Object s) {
		return s == null || "".equals(s);
	}

	private DBUtil() {
	}

	final static String url = prop.getProperty("url");// "jdbc:mysql://localhost:3306/java46?useUnicode=true&characterEncoding=utf8";

	public static Connection getConnection() {
		try {
			return DriverManager.getConnection(url, prop.getProperty("user"),
					prop.getProperty("password"));
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return null;
	}

	public static void closeAll(ResultSet r, Statement s, Connection c) {
		close(r);
		close(s);
		close(c);
	}

	public static void close(ResultSet r) {
		if (r != null)
			try {
				r.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
	}

	public static void close(Statement r) {
		if (r != null)
			try {
				r.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
	}

	public static void close(Connection r) {
		if (r != null)
			try {
				r.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
	}

	/**
	 * 通用的CUD操作
	 * 
	 * @param sql
	 * @param args
	 * @return
	 */
	public static int executeUpdate(String sql, Object... args) {
		Connection con = getConnection();
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				// 有一些属性需要单独处理
				if (args[i] instanceof java.util.Date) {
					java.util.Date d = (Date) args[i];
					ps.setDate(i + 1,
							d == null ? null : new java.sql.Date(d.getTime()));
					continue;
				}
				ps.setObject(i + 1, args[i]);
			}
			return ps.executeUpdate();
		} catch (SQLException e) {
			// 忽略异常
			e.printStackTrace();
		} finally {
			close(ps);
			close(con);
		}
		return 0;
	}

	/**
	 * 通用的查询方法 。。。反射，Field;元信息
	 * 
	 * @param sql
	 * @param args
	 * @return
	 */
	public static <T extends Serializable> List<T> query(String sql,
			Class<T> t, Object... args) {
		Connection con = getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> datas = new ArrayList<T>();

		try {
			ps = con.prepareStatement(sql);
			for (int i = 0; i < args.length; i++)
				ps.setObject(i + 1, args[i]);
			rs = ps.executeQuery();
			ResultSetMetaData rm = rs.getMetaData();
			while (rs.next()) {
				T obj = t.newInstance();// new
				for (int i = 1; i <= rm.getColumnCount(); i++) {
					String fieldName = rm.getColumnLabel(i);// 属性
					Field f = t.getDeclaredField(fieldName);
					f.setAccessible(true);
					f.set(obj, rs.getObject(fieldName));
				}
				datas.add(obj);
			}
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} finally {
			closeAll(rs, ps, con);
		}

		return datas;
	}
}
